from requests_html import HTMLSession
import random


# 自变量：不能选-> 多选、比例题、比重
# 因变量：不能选-> 比重

# 默认->信效度+因子分析+比例分析
# 选择->差异分析，相关分析，回归分析
# 中介+调节

def explain_www_wjx_cn(url: str):
    def deal_rate(q, q_type_int: int, q_type_name: str, result: [], data_index):
        """
        比重题
        :param data_index:
        :param q:
        :param q_type_int:
        :param q_type_name:
        :param result:
        :return:
        """
        data_index_arr = []
        min_oper_num, max_oper_num = 0, 100
        title = q.find('.field-label', first=True).text
        sub_titles = [t.text for t in q.find('.title')]
        children = []
        for i in range(len(sub_titles)):
            cur_title = title + '(' + sub_titles[i] + ")"
            data_index_obj = {'index': data_index, 'title': cur_title, 'option_count': 1,
                              'type': q_type_int, 'valid_values': list(range(101))}  # 解析出来的数据库索引对应的列名称
            cur_title = {'parent_id': q.attrs.get('topic'), 'title_id': i + 1, 'title': cur_title,
                         'type': q_type_int, 'type_name': q_type_name, 'max_oper_num': max_oper_num,
                         'min_oper_num': min_oper_num, 'options': None,
                         'data_index': data_index_obj}
            children.append(cur_title)
            data_index_arr.append(data_index_obj)
            data_index += 1
        cur_res = {'title_id': q.attrs.get('topic'), 'title': title, 'type': q_type_int, 'type_name': q_type_name,
                   'options': None, 'children': children, 'data_index': data_index_arr}
        result.append(cur_res)
        return data_index

    def deal_slide(q, q_type_int: int, q_type_name: str, result: [], data_index):
        """
        处理滑动比例题
        :param q:
        :param q_type_int:
        :param q_type_name:
        :param result:
        :return:
        """
        data_index_arr = []
        min_oper_num, max_oper_num = 0, 100
        title = q.find('.field-label', first=True).text
        sub_titles = [t.text for t in q.find('.itemTitleSpan')]
        children = []
        for i in range(len(sub_titles)):
            cur_title = title + '(' + sub_titles[i] + ")"
            data_index_obj = {'index': data_index, 'title': cur_title, 'option_count': 1,
                              'type': q_type_int, 'valid_values': list(range(101))}  # 解析出来的数据库索引对应的列名称
            cur_title = {'parent_id': q.attrs.get('topic'), 'title_id': i + 1, 'title': sub_titles[i],
                         'type': q_type_int, 'type_name': q_type_name, 'max_oper_num': max_oper_num,
                         'min_oper_num': min_oper_num, 'options': None,
                         'data_index': data_index_obj}
            children.append(cur_title)
            data_index_arr.append(data_index_obj)
            data_index += 1

        cur_res = {'title_id': q.attrs.get('topic'), 'title': title, 'type': q_type_int, 'type_name': q_type_name,
                   'options': None, 'children': children, 'data_index': data_index_arr}
        result.append(cur_res)
        return data_index

    def deal_matrix(q, q_type_int: int, q_type_name: str, result: [], data_index):
        data_index_arr = []  # 生成后的数据索引
        title = q.find('.field-label', first=True).text
        sub_titles = [t.text for t in q.find('.rowtitlediv')]
        choices = [t.text for t in q.find('th')][1:]
        option_arr = []  # 选项的数组
        valid_values = []
        for i in range(len(choices)):
            option_arr.append(
                {'name': choices[i], 'value': i + 1, 'rate': random.randint(1, 100), 'is_text': False})
            valid_values.append(i + 1)
        children = []
        for i in range(len(sub_titles)):
            cur_title = title + '(' + sub_titles[i] + ")"
            data_index_obj = {'index': data_index, 'title': cur_title, 'option_count': len(choices),
                              'type': q_type_int, 'valid_values': valid_values}  # 解析出来的数据库索引对应的列名称
            cur_title = {'parent_id': q.attrs.get('topic'), 'title_id': i + 1, 'title': sub_titles[i],
                         'type': q_type_int, 'type_name': q_type_name, 'options': option_arr,
                         'data_index': data_index_obj}
            children.append(cur_title)
            data_index_arr.append(data_index_obj)
            data_index += 1

        cur_res = {'title_id': q.attrs.get('topic'), 'title': title, 'type': q_type_int, 'type_name': q_type_name,
                   'options': None, 'children': children, 'data_index': data_index_arr}
        result.append(cur_res)
        return data_index

    def deal_scales(q, q_type_int: int, q_type_name: str, result: [], data_index):
        """
        处理量表题
        :param q:
        :param q_type_int:
        :param q_type_name:
        :param result:  title_id -> 标题id，title-> 标题，type->题目类型，type_name->题目类型中文名称，
                        options->选项，is_text->是否输入文字，data_index：index->数据库的索引，option_count->该题的选项数量
        :return:
        """
        title = q.find('.field-label', first=True).text
        choices = [t for t in q.find('a')]
        cur_options = []
        valid_values = []
        for i in range(len(choices)):
            cur_options.append(
                {'name': choices[i].attrs.get('title'), 'value': choices[i].attrs.get('val'),
                 'rate': random.randint(1, 100), 'is_text': False})
            valid_values.append(choices[i].attrs.get('val'))
        data_index_obj = {'index': data_index, 'title': title, 'option_count': len(choices),
                          'type': q_type_int, 'valid_values': valid_values}  # 解析出来的数据库索引对应的列名称
        cur_res = {'title_id': q.attrs.get('topic'), 'title': title, 'type': q_type_int, 'type_name': q_type_name,
                   'options': cur_options, 'data_index': [data_index_obj]}
        result.append(cur_res)
        data_index += 1
        return data_index

    def deal_sort(q, q_type_int: int, q_type_name: str, result: [], data_index):
        """
        处理排序题
        :param q:
        :param q_type_int:
        :param q_type_name:
        :param result:
        :return:
        """
        data_index_arr = []
        min_oper_num, max_oper_num = 1, 1
        title = q.find('.field-label', first=True).text
        choices = [t for t in q.find('.ui-li-static')]
        valid_values = [i + 1 for i in range(len(choices))]
        option_arr = []  # 选项的数组
        for i in range(len(choices)):
            cur_title = title + '(' + choices[i].text + ")"
            data_index_obj = {'index': data_index, 'title': cur_title, 'option_count': len(choices),
                              'type': q_type_int, 'valid_values': valid_values}  # 解析出来的数据库索引对应的列名称
            data_index_arr.append(data_index_obj)
            data_index += 1
            text = choices[i].find('.ui-text')
            is_text = True if text else False
            custom = choices[i].find('.custom', first=True)
            option_arr.append(
                {'name': choices[i].text, 'value': custom.attrs.get('value'),
                 'rate': random.randint(1, 100), 'is_text': is_text})
        max_oper_num = len(option_arr)
        cur_res = {'title_id': q.attrs.get('topic'), 'title': title, 'type': q_type_int, 'type_name': q_type_name,
                   'min_oper_num': min_oper_num, 'max_oper_num': max_oper_num, 'options': option_arr,
                   'data_index': data_index_arr}
        result.append(cur_res)
        return data_index

    def deal_fill_in(q, q_type_int: int, q_type_name: str, result: [], data_index):
        """
        处理填空题
        :param q:
        :param q_type_int:
        :param q_type_name:
        :param result:
        :return:    title_id -> 标题id，title-> 标题，type->题目类型，type_name->题目类型中文名称，
                    options->选项，is_text->是否输入文字，data_index：index->数据库的索引，option_count->该题的选项数量
        """
        title = q.find('.field-label', first=True).text
        cur_title = title
        data_index_obj = {'index': data_index, 'title': cur_title, 'option_count': 1,
                          'type': q_type_int}  # 解析出来的数据库索引对应的列名称
        cur_res = {'title_id': q.attrs.get('topic'), 'title': title, 'type': q_type_int, 'type_name': q_type_name,
                   'options': None, 'is_text': True, 'data_index': [data_index_obj]}
        result.append(cur_res)
        data_index += 1
        return data_index

    def deal_single_option(q, q_type_int: int, q_type_name: str, result: [], data_index):
        """
        处理下拉选择
        :param q:
        :param q_type_int:
        :param q_type_name:
        :param result:
        :return:
        """
        title = q.find('.field-label', first=True).text
        choices = [t for t in q.find('option')]
        option_arr = []  # 选项的数组
        valid_values = []  #
        for i in range(len(choices)):
            option_arr.append(
                {'name': choices[i].text, 'value': choices[i].attrs.get('value'), 'rate': random.randint(1, 100),
                 'is_text': False})
            valid_values.append(choices[i].attrs.get('value'))
        data_index_obj = {'index': data_index, 'title': title, 'option_count': len(choices),
                          'type': q_type_int, 'valid_values': valid_values}  # 解析出来的数据库索引对应的列名称
        cur_res = {'title_id': q.attrs.get('topic'), 'title': title, 'type': q_type_int, 'type_name': q_type_name,
                   'options': option_arr, 'data_index': [data_index_obj]}
        result.append(cur_res)
        data_index += 1
        return data_index

    def deal_single(q, q_type_int: int, q_type_name: str, result: [], data_index):
        """
        处理单选题
        :param q:
        :param q_type_int:
        :param q_type_name:
        :param result:  title_id -> 标题id，title-> 标题，type->题目类型，type_name->题目类型中文名称，
                        options->选项，is_text->是否输入文字，data_index：index->数据库的索引，option_count->该题的选项数量
        :return:
        """
        title = q.find('.field-label', first=True).text
        choices = [t for t in q.find('.ui-radio')]
        option_arr = []  # 选项的数组
        valid_values = []  #
        for i in range(len(choices)):
            text = choices[i].find('.ui-text')
            is_text = True if text else False
            option_arr.append(
                {'name': choices[i].text, 'value': i + 1, 'rate': random.randint(1, 100),
                 'is_text': is_text})
            valid_values.append(i + 1)
        data_index_obj = {'index': data_index, 'title': title, 'option_count': len(choices),
                          'type': q_type_int, 'valid_values': valid_values}  # 解析出来的数据库索引对应的列名称
        cur_res = {'title_id': q.attrs.get('topic'), 'title': title, 'type': q_type_int, 'type_name': q_type_name,
                   'options': option_arr, 'data_index': [data_index_obj]}
        result.append(cur_res)
        data_index += 1
        return data_index

    def deal_multiple(q, q_type_int: int, q_type_name: str, result: [], data_index):
        """
        处理多选题
        :param q:
        :param q_type_int:
        :param q_type_name:
        :param result:  title_id -> 标题id，title-> 标题，type->题目类型，type_name->题目类型中文名称，
                        options->选项，is_text->是否输入文字，data_index：index->数据库的索引，option_count->该题的选项数量
        :return:
        """
        data_index_arr = []
        min_oper_num, max_oper_num = 1, 1
        title = q.find('.field-label', first=True).text
        choices = [t for t in q.find('.ui-checkbox')]
        option_arr = []  # 选项的数组
        for i in range(len(choices)):
            text = choices[i].find('.ui-text')
            is_text = True if text else False
            cur_title = title + "(" + choices[i].text + ")"
            data_index_obj = {'index': data_index, 'title': cur_title, 'option_count': 1,
                              'type': q_type_int, 'valid_values': [0, 1]}  # 解析出来的数据库索引对应的列名称
            data_index_arr.append(data_index_obj)
            data_index += 1
            option_arr.append(
                {'name': choices[i].text, 'value': i + 1, 'rate': random.randint(1, 100), 'is_text': is_text})
        max_oper_num = len(option_arr)
        cur_res = {'title_id': q.attrs.get('topic'), 'title': title, 'type': q_type_int, 'type_name': q_type_name,
                   'min_oper_num': min_oper_num, 'max_oper_num': max_oper_num, 'options': option_arr,
                   'data_index': data_index_arr}
        result.append(cur_res)

        return data_index

    def explain_questions(q, result: [], index):
        """
        解析wjx问卷
        :param q: 问卷的html代码
        :param result: 返回的结果
        :param index: 当前题目的数据库索引
        :return:
        """
        q_type = q.attrs.get('type')
        q_type_int = int(q_type)
        q_type_name = ''
        if q_type_int == 1:
            q_type_name = '填空题'
            index = deal_fill_in(q, q_type_int, q_type_name, result, index)
        elif q_type_int == 2:
            pass
        elif q_type_int == 3:
            q_type_name = '单选题'
            index = deal_single(q, q_type_int, q_type_name, result, index)
        elif q_type_int == 4:
            q_type_name = '多选题'
            index = deal_multiple(q, q_type_int, q_type_name, result, index)
        elif q_type_int == 5:
            q_type_name = '量表题'
            index = deal_scales(q, q_type_int, q_type_name, result, index)
        elif q_type_int == 6:
            q_type_name = '矩阵题'
            index = deal_matrix(q, q_type_int, q_type_name, result, index)
        elif q_type_int == 7:
            q_type_name = '单选题(下拉选择)'
            index = deal_single_option(q, q_type_int, q_type_name, result, index)
        elif q_type_int == 8:
            pass
        elif q_type_int == 9:
            q_type_name = '滑动题'
            index = deal_slide(q, q_type_int, q_type_name, result, index)
        elif q_type_int == 10:
            pass
        elif q_type_int == 11:
            q_type_name = '排序题'
            index = deal_sort(q, q_type_int, q_type_name, result, index)
        elif q_type_int == 12:
            q_type_name = '比重题'
            index = deal_rate(q, q_type_int, q_type_name, result, index)
        return index

    def do_explain(resp, res_list, index):
        questions = resp.html.find('fieldset', first=True).find('.field.ui-field-contain')
        for i, q in enumerate(questions):
            index = explain_questions(q, res_list, index)
        return index

    session = HTMLSession()
    response = session.get(url)
    session.close()
    res_list = []
    total_data_index = 0
    total_data_index = do_explain(response, res_list, total_data_index)
    res = {'total_data_index': total_data_index, 'list': res_list}

    return res
